//
// Created by kqzhang on 2022/3/17.
//

#include "File.h"

File::File(string value) : root(value) {}

void File::setRoot(string &value) {
    this->root = value;
}

string File::getRoot() {
    return this->root;
}

//vector<int> File::getSiteBandWidth() {
//    vector<int> servers_Bandwidth;
//
//    // open site_bandwidth.csv
//    vector<vector<string>> spiltValue;
//    string path = root + "data/site_bandwidth.csv";
//    getDataFromFile(path, spiltValue);
//
//    // cast string to PSI
//    for (auto value : spiltValue) {
//        if (value[0] == "site_name" && value[1] == "bandwidth")
//            continue;
//        servers_Bandwidth.push_back(atoi(value[1].c_str()));
//    }
//
//    return servers_Bandwidth;
//}
//
//vector<vector<int>> File::getQos() {
//    vector<vector<int>> qos;
//
//    // open qos.csv
//    vector<vector<string>> spiltValue;
//    string path = root + "data/qos.csv";
//    getDataFromFile(path, spiltValue);
//
//    // cast string int PSVi
//    for (int i = 0; i < spiltValue.size(); i++) {
//        if (i == 0) continue;
//        vector<int> lineValue;
//        for (int j = 1; j < spiltValue[0].size(); j++) {
//            lineValue.push_back(atoi(spiltValue[i][j].c_str()));
//        }
//        qos.push_back(lineValue);
//    }
//
//    return qos;
//}
//
//vector<vector<int>> File::getDemand() {
//    vector<vector<int>> demand;
//
//    // open demand.csv
//    vector<vector<string>> spiltValue;
//    string path = root + "data/demand.csv";
//    getDataFromFile(path, spiltValue);
//
//    // cast string int PSVi
//    for (int i = 0; i < spiltValue.size(); i++) {
//        if (i == 0) continue;
//        vector<int> lineValue;
//        for (int j = 1; j < spiltValue[0].size(); j++) {
//            lineValue.push_back(atoi(spiltValue[i][j].c_str()));
//        }
//        demand.push_back(lineValue);
//    }
//
//    return demand;
//}
//
//vector<string> File::getSiteId() {
//    vector<string> siteId;
//
//    // open site_bandwidth.csv
//    vector<vector<string>> spiltValue;
//    string path = root + "data/site_bandwidth.csv";
//    getDataFromFile(path, spiltValue);
//
//    // get site ID
//    for (auto value : spiltValue) {
//        if (value[0] == "site_name" && value[1] == "bandwidth")
//            continue;
//        siteId.push_back(value[0]);
//    }
//
//    return siteId;
//}
//
//vector<string> File::getUserId() {
//    vector<string> userId;
//
//    // open qos.csv
//    vector<vector<string>> spiltValue;
//    string path = root + "data/qos.csv";
//    getDataFromFile(path, spiltValue);
//
//    // get user id
//    for (int i = 0; i < spiltValue[0].size(); i++) {
//        if (i == 0) continue;
//        userId.push_back(spiltValue[0][i]);
//    }
//
//    return userId;
//}

void File::getSiteBandWidth(vector<int> &servers_Bandwidth, vector<string> &site) {
    // open site_bandwidth.csv
    map<string, int> siteMap;
    vector<vector<string>> spiltValue;
    string path = root + "data/site_bandwidth.csv";
    getDataFromFile(path, spiltValue);

    // cast string to PSI
    vector<int> demo;
    int length = spiltValue.size();
    for (int i = 0; i < length; i++) {
        if (i == 0)
            continue;
	    auto value = spiltValue[i];
        siteMap.insert(pair<string, int>(value[0], i - 1));
        demo.push_back(atoi(value[1].c_str()));
    }

    for (int i = 0; i < demo.size(); i++) {
        servers_Bandwidth.push_back(demo[siteMap[site[i]]]);
    }
}

void File::getQos(vector<vector<int>> &qos) {
    // open qos.csv
    vector<vector<string>> spiltValue;
    string path = root + "data/qos.csv";
    getDataFromFile(path, spiltValue);

    // cast string int PSVi
    for (int i = 0; i < spiltValue.size(); i++) {
        if (i == 0) continue;
        vector<int> lineValue;
        for (int j = 1; j < spiltValue[0].size(); j++) {
            lineValue.push_back(atoi(spiltValue[i][j].c_str()));
        }
        qos.push_back(lineValue);
    }
}

void File::getDemand(vector<vector<int>> &demand, vector<string> &user) {
    // open demand.csv
    map<string, int> mapUser;
    vector<vector<string>> spiltValue;
    string path = root + "data/demand.csv";
    getDataFromFile(path, spiltValue);

    // getUserMap
    int length = spiltValue[0].size();
    for (int i = 0; i < length; i++) {
        if (i == 0) continue;
        if (i == length - 1) {
            int finalLength = spiltValue[0][i].size();
            mapUser.insert(pair<string, int>(spiltValue[0][i].substr(0, finalLength - 1), i - 1));
        } else {
            mapUser.insert(pair<string, int>(spiltValue[0][i], i - 1));
        }
    }

    // cast string int PSVi
    vector<vector<int>> demo;
    for (int i = 0; i < spiltValue.size(); i++) {
        if (i == 0) continue;
        vector<int> lineValue;
        for (int j = 1; j < spiltValue[0].size(); j++) {
            lineValue.push_back(atoi(spiltValue[i][j].c_str()));
        }
        demo.push_back(lineValue);
    }

    vector<vector<int>> orderDemand(demo.size(), vector<int>(demo[0].size()));
    for (int i = 0; i < demo.size(); i++) {
        for (int j = 0; j < demo[0].size(); j++) {
            orderDemand[i][j] = demo[i][mapUser[user[j]]];
        }
    }

    demand = orderDemand;
}

void File::getSiteId(vector<string> &siteId) {
    // open site_bandwidth.csv
    vector<vector<string>> spiltValue;
    string path = root + "data/qos.csv";
    getDataFromFile(path, spiltValue);

    // get site ID
    int length = spiltValue.size();
    for (int i = 0; i < length; i++) {
        if (i == 0) continue;
	    auto value = spiltValue[i];

	    siteId.push_back(value[0]);
    }
}

void File::getUserId(vector<string> &userId) {
    // open qos.csv
    vector<vector<string>> spiltValue;
    string path = root + "data/qos.csv";
    getDataFromFile(path, spiltValue);

    // get user id
    int length = spiltValue[0].size();
    for (int i = 0; i < length; i++) {
        if (i == 0) continue;
        if (i == length - 1) {
	        int finalLength = spiltValue[0][i].size();
	        userId.push_back(spiltValue[0][i].substr(0, finalLength - 1));
	    } else {
            userId.push_back(spiltValue[0][i]);
        }
    }
}

int File::getQosConstraint() {

    //open config.ini
    string path = root + "data/config.ini";
    vector<vector<string>> spiltValue;
    getDataFromFile(path, spiltValue);

    // get qos_constraint
    string value = spiltValue[1][0];
    int size = atoi(value.substr(15, value.size() - 15).c_str());

    return size;
}

void File::getDataFromFile(string path, vector<vector<string>> &spiltValue) {
    ifstream csvFile(path, ios::in);
    if (!csvFile) {
        cout << "open file: " << path << " error" << endl;
        exit(1);
    }
    string lineValue;
    while (getline(csvFile, lineValue)) {
        istringstream readStr(lineValue);
        string field;
        vector<string> fields;
        while (getline(readStr, field, ',')) {
            fields.push_back(field);
        }
        spiltValue.push_back(fields);
    }
}



